﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace StableDiffusionTools.Utils
{
    public static class FontUtil
    {
        [DllImport("gdi32.dll", CharSet = CharSet.Auto)]
        private static extern bool GetTextMetrics(IntPtr hdc, out TEXTMETRICW lptm);

        [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool DeleteObject(IntPtr hObject);

        [DllImport("gdi32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiObj);

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct TEXTMETRICW
        {
            public int tmHeight;
            public int tmAscent;
            public int tmDescent;
            public int tmInternalLeading;
            public int tmExternalLeading;
            public int tmAveCharWidth;
            public int tmMaxCharWidth;
            public int tmWeight;
            public int tmOverhang;
            public int tmDigitizedAspectX;
            public int tmDigitizedAspectY;
            public ushort tmFirstChar;
            public ushort tmLastChar;
            public ushort tmDefaultChar;
            public ushort tmBreakChar;
            public byte tmItalic;
            public byte tmUnderlined;
            public byte tmStruckOut;
            public byte tmPitchAndFamily;
            public byte tmCharSet;
        }

        private static IEnumerable<FontFamily> GetFixedWidthFonts(IDeviceContext dc)
        {
            IntPtr hDC = dc.GetHdc();

            foreach (FontFamily oFontFamily in FontFamily.Families)
            {
                using (Font oFont = new Font(oFontFamily, 10))
                {
                    IntPtr hFont = IntPtr.Zero;
                    IntPtr hFontDefault = IntPtr.Zero;

                    try
                    {
                        TEXTMETRICW oTextMetric;

                        hFont = oFont.ToHfont();
                        hFontDefault = SelectObject(hDC, hFont);

                        if (GetTextMetrics(hDC, out oTextMetric))
                        {
                            //Monospace
                            if ((oTextMetric.tmPitchAndFamily & 1) == 0)
                            {
                                yield return oFontFamily;
                            }
                        }
                    }
                    finally
                    {
                        if (hFontDefault != IntPtr.Zero)
                        {
                            SelectObject(hDC, hFontDefault);
                        }

                        if (hFont != IntPtr.Zero)
                        {
                            DeleteObject(hFont);
                        }
                    }
                }
            }

            dc.ReleaseHdc();
        }
    }
}
